/**
 *  功能：SEN0244 gravity TDS Sensor 液体浑浊检测设备
 *  作者：tuut
 *  时间：2023-11-28
 *  描述：
 *      1.设备初始化
 *      2.设备周边温度,读取检测设备在液体中的电阻数值
 *      3.根据电阻数值，计算检测液体浑浊度
 *      4.测试官方方法的使用
*/
#include "Sketch_oct31b_tds.h"  // 功能：SEN0244 gravity TDS 设备引用 液体浑浊检测设备
#include <Arduino.h>
/****************************************SEN0244 part****************************************/
Sketch_oct31b_tds::Sketch_oct31b_tds() {
  Serial.println("Sketch_oct31b_tds Object Created.");
  ONE_WIRE_BUS_PIN = TdsSensorPin;
}

Sketch_oct31b_tds::Sketch_oct31b_tds(int cusSensorPin) {
  Serial.println("Sketch_oct31b_tds Object Created.");
  ONE_WIRE_BUS_PIN = cusSensorPin;
}

Sketch_oct31b_tds::~Sketch_oct31b_tds() {
  Serial.println("Sketch_oct31b_tds Object Deleted.");
}

int Sketch_oct31b_tds::getPin() {
  return ONE_WIRE_BUS_PIN;
}

float Sketch_oct31b_tds::getTds() {
  return tds_point;
}

void Sketch_oct31b_tds::setDs18b20Temperature(float currentTemperature) {
  temperature = currentTemperature;
}

/**
 * 功能描述：初始化TDS浑浊探测棒
 */
void Sketch_oct31b_tds::initSEN0244DevManager() {
  cal_delayStart = millis();
  pinMode(ONE_WIRE_BUS_PIN, INPUT);
}

void Sketch_oct31b_tds::loadTDSAPI(long _interval) {
  if ((millis() - cal_delayStart) >= _interval) {
    tds_point = loadData();
    cal_delayStart = millis();
  }
}

float Sketch_oct31b_tds::loadData() {
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //每40毫秒，从ADC读取模拟值
  {
    // Serial.println("每40毫秒，从ADC读取模拟值");
    analogSampleTimepoint = millis();
    for (int BufferIndex = 0; BufferIndex < readCount; BufferIndex++) {
      // Serial.println("读取传感器输出引脚模拟电压存储到缓冲区");
      Buffer[BufferIndex] = analogRead(ONE_WIRE_BUS_PIN);  //读取传感器输出引脚模拟电压存储到缓冲区
      // Serial.printf("Buffer[%d]: %d \n", BufferIndex, Buffer[BufferIndex]);
    }
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      BufferTemp[copyIndex] = Buffer[copyIndex];
    //通过中值滤波算法读取更稳定的模拟值，并转换为电压值。getMedianNum见下
    // Serial.println("通过中值滤波算法读取更稳定的模拟值，并转换为电压值。getMedianNum见下");
    averageVoltage = getMedianNum(BufferTemp, SCOUNT) * (float)VREF / 1024.0;
    //temperture待测溶液温度  compensationCoefficient温度校正系数
    //温度补偿公式: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    // Serial.println("temperture：待测溶液温度  compensationCoefficient：温度校正系数");
    compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0);
    //温度补偿
    // Serial.println("温度补偿");
    compensationVolatge = averageVoltage / compensationCoefficient;
    //转换为电压值,根据标准曲线
    // Serial.println("转换为电压值,根据标准曲线");
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5;
  }
  Serial.print("{");
  Serial.print("'temperature':'");
  Serial.print(temperature, 2);
  Serial.print("C',");
  Serial.print("'voltage':'");
  Serial.print(averageVoltage, 2);
  Serial.print("V',");
  Serial.print("'TDS_Value':'");
  Serial.print(tdsValue, 0);
  Serial.print("Ppm'");
  Serial.println("}");
  return tdsValue;
}

// 中值滤波     bArray[]数据源  iFilterLen数据个数
int Sketch_oct31b_tds::getMedianNum(int bArray[], int iFilterLen) {
  //  Serial.printf("\n滤波……");
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++) {
    bTab[i] = bArray[i];
    //    Serial.printf("\n bArray[%d]: %d ", i, bArray[i]);
  }
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {  //使升序排列便于取中值bTemp
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)              //和1相与判断奇偶
    bTemp = bTab[(iFilterLen - 1) / 2];  //奇数个元素取中值
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;  //偶数个元素取中值
  return bTemp;
}